package com.tjvib.view.activity;

import static com.tjvib.Constants.PARAM_ACCX;
import static com.tjvib.Constants.PARAM_ACCY;
import static com.tjvib.Constants.PARAM_ACCZ;
import static com.tjvib.Constants.PARAM_ALL;
import static com.tjvib.Constants.SUCCESS;

import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.Spinner;
import android.widget.SpinnerAdapter;
import android.widget.TextView;

import com.bin.david.form.annotation.SmartColumn;
import com.bin.david.form.core.SmartTable;
import com.bin.david.form.core.TableConfig;
import com.jjoe64.graphview.GraphView;
import com.jjoe64.graphview.LegendRenderer;
import com.jjoe64.graphview.series.DataPoint;
import com.jjoe64.graphview.series.DataPointInterface;
import com.jjoe64.graphview.series.LineGraphSeries;
import com.jjoe64.graphview.series.OnDataPointTapListener;
import com.jjoe64.graphview.series.PointsGraphSeries;
import com.jjoe64.graphview.series.Series;
import com.tjvib.Constants;
import com.tjvib.R;
import com.tjvib.base.BaseActivity;
import com.tjvib.common.Callback;
import com.tjvib.math.Complex;
import com.tjvib.math.FFT;
import com.tjvib.sensor.SensorData;
import com.tjvib.util.LogUtil;
import com.tjvib.util.Manager.DataSetManager;
import com.tjvib.presenter.BasePresenter;
import com.tjvib.util.Manager.AppManager;
import com.tjvib.util.Manager.UserManager;
import com.tjvib.util.PoiUtil;
import com.tjvib.util.PressUtil;
import com.tjvib.util.ToastUtil;
import com.tjvib.util.retrofit.BaseResponse;
import com.tjvib.util.retrofit.RetrofitHelper;
import com.tjvib.view.dialog.LoadingDialog;
import com.tjvib.widget.AndroidScheduler;
import com.tjvib.widget.TitleLayout;

import org.json.JSONException;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

public class CensusActivity extends BaseActivity {
    private Spinner cen_sp_sensor;
    private SmartTable cen_st_data;
    private TextView cen_tv_hint;
    private RadioButton cen_rb_all, cen_rb_accx, cen_rb_accy, cen_rb_accz;
    private GraphView cen_gv_data;
    private Button cen_btn_export;
    private TitleLayout cen_tit;

    private DataSetManager dataSetManager = DataSetManager.getInstance();
    private List<String> sensorList = new ArrayList<>();
    private int currIndex = -2;

    private String sensorSelect = "";
    List<? extends SensorData> sensorDataList = new ArrayList<>();
    LineGraphSeries<DataPoint> mSeries1 = new LineGraphSeries<>(),
            mSeries2 = new LineGraphSeries<>(),
            mSeries3 = new LineGraphSeries<>();
    

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    protected int initLayout() {
        return R.layout.activity_census;
    }

    @Override
    protected boolean initView() {
        cen_tit = findViewById(R.id.cen_tit);
        cen_tit.setTitle(getIntent().getStringExtra("METHOD"));

        cen_sp_sensor = findViewById(R.id.cen_sp_sensor);
        cen_st_data = findViewById(R.id.cen_st_data);
        cen_tv_hint = findViewById(R.id.cen_tv_hint);

        cen_btn_export = findViewById(R.id.cen_btn_export);
        cen_btn_export.setOnClickListener(v-> {
                if (currIndex != -2) {
                    FileReadWriteTask fileReadWriteTask = new FileReadWriteTask();
                    fileReadWriteTask.execute();
                } else
                    ToastUtil.show("导出失败，表格不应为空");
        });

        cen_gv_data = findViewById(R.id.cen_gv_data);

        cen_rb_all = findViewById(R.id.cen_rb_all);
        cen_rb_accx = findViewById(R.id.cen_rb_accx);
        cen_rb_accy = findViewById(R.id.cen_rb_accy);
        cen_rb_accz = findViewById(R.id.cen_rb_accz);
        cen_rb_all.setOnCheckedChangeListener((compoundButton, b) -> {
            if (b) onAxisChange(PARAM_ALL);
        });
        cen_rb_accx.setOnCheckedChangeListener((compoundButton, b) -> {
            if (b) onAxisChange(PARAM_ACCX);
        });
        cen_rb_accy.setOnCheckedChangeListener((compoundButton, b) -> {
            if (b) onAxisChange(PARAM_ACCY);
        });
        cen_rb_accz.setOnCheckedChangeListener((compoundButton, b) -> {
            if (b) onAxisChange(PARAM_ACCZ);
        });

        return true;
    }

    @Override
    protected boolean initData() {
        ToastUtil.show("左右拖动表格查看完整分析结果");
        sensorList = dataSetManager.getSensorList();
        SpinnerAdapter spinnerAdapter = new ArrayAdapter<>(this, R.layout.item_spinner_dropdown, sensorList);
        cen_sp_sensor.setAdapter(spinnerAdapter);
        cen_sp_sensor.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                cen_rb_all.setChecked(true);
                sensorSelect = sensorList.get(position);
                drawGraph();
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });

        if (dataSetManager.getDataSetInfo().getType().equals("local")) {
            List<CensusItem> data = new ArrayList<>(Arrays.asList(
                    new CensusItem("AccX", dataSetManager.getAccMax(-1, 0, 4),
                            dataSetManager.runningRMS(-1, 0, 1, 4),
                            dataSetManager.runningRMS(-1, 0, 10, 4),
                            dataSetManager.runningRMS(-1, 0, 4)),
                    new CensusItem("AccY", dataSetManager.getAccMax(-1, 1, 4),
                            dataSetManager.runningRMS(-1, 1, 1, 4),
                            dataSetManager.runningRMS(-1, 1, 10, 4),
                            dataSetManager.runningRMS(-1, 1, 4)),
                    new CensusItem("AccZ", dataSetManager.getAccMax(-1, 2, 4),
                            dataSetManager.runningRMS(-1, 2, 1, 4),
                            dataSetManager.runningRMS(-1, 2, 10, 4),
                            dataSetManager.runningRMS(-1, 2, 4))
            ));
            currIndex = -1;
            cen_st_data.setData(data);
            cen_tv_hint.setVisibility(View.INVISIBLE);
        } else {
            if (!sensorList.isEmpty()) {
                int firstImuId = Integer.parseInt(sensorList.get(0));
                List<CensusItem> data = new ArrayList<>(Arrays.asList(
                        new CensusItem("AccX", dataSetManager.getAccMax(firstImuId, 0, 4),
                                dataSetManager.runningRMS(firstImuId, 0, 1, 4),
                                dataSetManager.runningRMS(firstImuId, 0, 10, 4),
                                dataSetManager.runningRMS(-1, 2, 4)),
                        new CensusItem("AccY", dataSetManager.getAccMax(firstImuId, 1, 4),
                                dataSetManager.runningRMS(firstImuId, 1, 1, 4),
                                dataSetManager.runningRMS(firstImuId, 1, 10, 4),
                                dataSetManager.runningRMS(-1, 2, 4)),
                        new CensusItem("AccZ", dataSetManager.getAccMax(firstImuId, 2, 4),
                                dataSetManager.runningRMS(firstImuId, 2, 1, 4),
                                dataSetManager.runningRMS(firstImuId, 2, 10, 4),
                                dataSetManager.runningRMS(-1, 2, 4))
                ));
                currIndex = firstImuId;
                cen_st_data.setData(data);
                cen_tv_hint.setVisibility(View.INVISIBLE);
            } else {
                currIndex = -2;
                cen_tv_hint.setVisibility(View.VISIBLE);
            }
        }

        TableConfig config = cen_st_data.getConfig();
        config.setShowXSequence(false);
        config.setShowYSequence(false);
        config.setShowTableTitle(false);

        return true;
    }

    @Override
    protected BasePresenter genPresenter() {
        return null;
    }


    private void drawGraph() {
        if (sensorSelect.equals("local"))
            sensorDataList = dataSetManager.getDataSetContent(-1);
        else
            sensorDataList = dataSetManager.getDataSetContent(Integer.parseInt(sensorSelect));

        initGraphView();
        runOnUiThread(() -> {
            mSeries1.setThickness(3);
            mSeries2.setThickness(3);
            mSeries3.setThickness(3);
            mSeries1.setColor(Color.BLUE);
            mSeries2.setColor(Color.GREEN);
            mSeries3.setColor(Color.RED);
            cen_gv_data.setBackgroundColor(Color.WHITE);
            mSeries1.setTitle("X");
            mSeries2.setTitle("Y");
            mSeries3.setTitle("Z");
            cen_gv_data.getLegendRenderer().setBackgroundColor(Color.TRANSPARENT);
            cen_gv_data.getLegendRenderer().setVisible(true);
            cen_gv_data.getLegendRenderer().setTextSize(18);
            cen_gv_data.getLegendRenderer().setTextColor(R.color.main_grey_2);
            cen_gv_data.getLegendRenderer().setAlign(LegendRenderer.LegendAlign.TOP);
            cen_gv_data.getGridLabelRenderer().setHorizontalAxisTitle("时间(s)");
            cen_gv_data.getGridLabelRenderer().setVerticalAxisTitle("幅值(g)");
            cen_gv_data.getGridLabelRenderer().setHorizontalAxisTitleTextSize(24);
            cen_gv_data.getGridLabelRenderer().setVerticalAxisTitleTextSize(24);
        });
    }


    public void initGraphView() {
        runOnUiThread(() -> {
            mSeries1.resetData(new DataPoint[]{});
            mSeries2.resetData(new DataPoint[]{});
            mSeries3.resetData(new DataPoint[]{});
            double miny = Double.MAX_VALUE, maxy = Double.MIN_VALUE;
            for (int m = 1; m < sensorDataList.size(); m++) {
                SensorData data = sensorDataList.get(m);
                float[] dataToShow = new float[3];
                int i = 0;
                while (i < 3) {
                    dataToShow[i] = data.acc[i];
                    maxy = Math.max(dataToShow[i], maxy);
                    miny = Math.min(dataToShow[i], miny);
                    i += 1;
                }

                mSeries1.appendData(new DataPoint(data.timestamp, dataToShow[0]), true, Integer.MAX_VALUE);
                mSeries2.appendData(new DataPoint(data.timestamp, dataToShow[1]), true, Integer.MAX_VALUE);
                mSeries3.appendData(new DataPoint(data.timestamp, dataToShow[2]), true, Integer.MAX_VALUE);
            }

            cen_gv_data.getViewport().setScrollable(true);
            cen_gv_data.getViewport().setScalable(true);
            if(sensorDataList.size() != 0) {
                cen_gv_data.getViewport().setMinX(0.0f);
                cen_gv_data.getViewport().setMaxX(sensorDataList.get(sensorDataList.size() - 1).timestamp);
                cen_gv_data.getViewport().setMaxY(maxy);
                cen_gv_data.getViewport().setMinY(miny);
            }
        });
    }


    private void onAxisChange(int axis) {
        cen_gv_data.removeAllSeries();
        switch (axis) {
            case PARAM_ACCX:
                cen_gv_data.addSeries(mSeries1);
                break;
            case PARAM_ACCY:
                cen_gv_data.addSeries(mSeries2);
                break;
            case PARAM_ACCZ:
                cen_gv_data.addSeries(mSeries3);
                break;
            case PARAM_ALL:
                cen_gv_data.addSeries(mSeries1);
                cen_gv_data.addSeries(mSeries2);
                cen_gv_data.addSeries(mSeries3);
        }
    }


    @com.bin.david.form.annotation.SmartTable(name = "时域指标统计")
    public static class CensusItem {
        @SmartColumn(id = 0, name = "指标")
        private String name;

        @SmartColumn(id = 1, name = "峰值(g)")
        private String maxValue;

        @SmartColumn(id = 2, name = "最大1s-rms值(g)")
        private String maxRms1;

        @SmartColumn(id = 3, name = "最大10s-rms值(g)")
        private String maxRms10;

        @SmartColumn(id = 4, name = "RMS值")
        private String rmsValue;

        public CensusItem(String name, String maxValue, String maxRms1, String maxRms10, String rmsValue) {
            this.name = name;
            this.maxValue = maxValue;
            this.maxRms1 = maxRms1;
            this.maxRms10 = maxRms10;
            this.rmsValue = rmsValue;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getMaxValue() {
            return maxValue;
        }

        public void setMaxValue(String maxValue) {
            this.maxValue = maxValue;
        }

        public String getMaxRms1() {
            return maxRms1;
        }

        public void setMaxRms1(String maxRms1) {
            this.maxRms1 = maxRms1;
        }

        public String getMaxRms10() {
            return maxRms10;
        }

        public void setMaxRms10(String maxRms10) {
            this.maxRms10 = maxRms10;
        }

        public String getRmsValue() {
            return rmsValue;
        }

        public void setRmsValue(String rmsValue) {
            this.rmsValue = rmsValue;
        }
    }


    private class FileReadWriteTask extends AsyncTask<Void, Void, Void> {
        private LoadingDialog loadingDialog = null;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            loadingDialog = new LoadingDialog(CensusActivity.this);
            loadingDialog.showDialog(CensusActivity.this, "正在输出报告...", 5);
        }

        @Override
        protected Void doInBackground(Void... voids) {
            SimpleDateFormat sdf = new SimpleDateFormat();
            sdf.applyPattern("yyyy-MM-dd HH:mm:ss");
            Date date = new Date();

            Map<String, String> replacements = new HashMap<>();
            replacements.put("【时间】", sdf.format(date));
            replacements.put("【姓名】", UserManager.getInstance().getUsername());
            replacements.put("【传感器】", cen_sp_sensor.getSelectedItem().toString().trim());
            replacements.put("【峰值AccX】", "" + dataSetManager.getAccMax(currIndex, 0, 4));
            replacements.put("【峰值AccY】", "" + dataSetManager.getAccMax(currIndex, 1, 4));
            replacements.put("【峰值AccZ】", "" + dataSetManager.getAccMax(currIndex, 2, 4));
            replacements.put("【最大1rmsAccX】", "" + dataSetManager.runningRMS(currIndex, 0, 1, 4));
            replacements.put("【最大1rmsAccY】", "" + dataSetManager.runningRMS(currIndex, 1, 1, 4));
            replacements.put("【最大1rmsAccZ】", "" + dataSetManager.runningRMS(currIndex, 2, 1, 4));
            replacements.put("【最大10rmsAccX】", "" + dataSetManager.runningRMS(currIndex, 0, 10, 4));
            replacements.put("【最大10rmsAccY】", "" + dataSetManager.runningRMS(currIndex, 1, 10, 4));
            replacements.put("【最大10rmsAccZ】", "" + dataSetManager.runningRMS(currIndex, 2, 10, 4));
            replacements.put("【RMSAccX】", "" + dataSetManager.runningRMS(currIndex, 0, 4));
            replacements.put("【RMSAccY】", "" + dataSetManager.runningRMS(currIndex, 1, 4));
            replacements.put("【RMSAccZ】", "" + dataSetManager.runningRMS(currIndex, 2, 4));
            Bitmap bitmap = PoiUtil.loadBitmapFromView(cen_gv_data);


            synchronized (PoiUtil.class) {
                PoiUtil.replaceFieldsWithImage2(bitmap, CensusActivity.this, Constants.METHOD_CENSUS,
                        sdf.format(date) + ".docx", replacements);
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void unused) {
            super.onPostExecute(unused);
            if(loadingDialog != null) loadingDialog.dismiss();
            ToastUtil.show("报告已保存");
        }
    }
}